<template>
	<view :class="pageClass" :style="pageStyle" v-if="pageReady" style="background-color: #F5F5F5;">
		<moxi-nav :set="navSet"></moxi-nav>
		<view class="voice_manage" :style="{ '--bg-color': app_color }">
			<view class="scrollY">
				<scroll-view style="height: 100%;" scroll-y @scrolltolower="scrolltolower">
					<view class="list" v-if="data.length > 0">
						<view class="item" v-for="item in data">
							<view class="taskInfo">
								<view class="title u-line-1">{{ item.name }}</view>
								<view class="desc u-line-1">{{ item.desc }}</view>
							</view>
							<view class="top">
								<view class="personInfo" v-if="item.config && item.config.voiceConfig">
									<view class="showImg">
										<image class="imageCss"
											:src="item.config.voiceConfig.img ? item.config.voiceConfig.img : ''"
											mode="scaleToFill" />
									</view>
									<view>
										<view class="title">
											<view class="u-line-1" style="font-weight: bold;">{{
												item.config.voiceConfig.speechType ? item.config.voiceConfig.speechType
													: '' }}</view>
											<!-- <view class="commend">精品</view> -->
										</view>
										<view class="name">{{ item.config.voiceConfig.speaker }}</view>
									</view>
								</view>
								<view class="controll" v-if="item.status == 1"
									:style="{ '--fail-color': (nowTime - item.c_time) > failTime ? '#999' : app_color }">
									<!-- 播放 -->
									<view @click="playAudio(item)">
										<u-icon
											:name="item.id == playId && playStatus ? 'pause-circle-fill' : 'play-circle-fill'"
											:color="(nowTime - item.c_time) > failTime ? '#999' : app_color"
											size="27"></u-icon>
									</view>
									<!-- 下载 -->
									<view class="circle" @click="downFile(item)">
										<u-icon name="download" color="#fff" size="14"></u-icon>
									</view>
									<!-- 删除 -->
									<!-- <view class="circle red" >
										<u-icon name="trash-fill" color="#fff" size="14"></u-icon>
									</view> -->
								</view>
							</view>
							<u-line></u-line>
							<view class="tips">
								<view class="time">{{ $u.timeFormat(item.c_time, 'yyyy-mm-dd hh:MM:ss') }}</view>
								<view class="">共{{ item.text_length }}字符</view>
							</view>
						</view>
					</view>
					<view style="padding: 10px 0;">
						<u-loadmore :status="status" loadingIcon="spinner" />
					</view>
				</scroll-view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			getInfo: {
				page: 1,
				page_num: 20
			},
			data: [],
			status: 'loading',
			voiceData: null,
			playId: -1, // 当前播放的id
			playTime: 0, // 当前播放的时间位置
			playStatus: false, // 播放状态
			playTimeMax: 0, // 播放总时长
			innerAudioContext: null, // 音频实例
			nowTime: 0, // 当前时间
			failTime: 60 * 60 * 24 * 3, // 有效时间 秒 * 分 * 时 * 天
		}
	},
	onLoad() {
		this.get();
		this.nowTime = Math.floor(Date.now() / 1000);
	},
	methods: {
		powerInfo(time, status) {
			if (time < this.nowTime - this.failTime) {
				this.msg('文件已过期');
				return 1;
			}
			if (status != 1) {
				this.msg('文件正在生成中...');
				return 2;
			}
			return 0;
		},
		playAudio(data) {
			let power = this.powerInfo(data.c_time, data.status);
			if (power != 0) {
				return;
			}
			let url = data.url;
			let id = data.id;

			if (this.playId !== id) {
				if (this.innerAudioContext) {
					// 如果有正在播放的音频，先暂停并释放资源
					this.innerAudioContext.stop();
					this.innerAudioContext.destroy();
				}
				// 切换播放内容，重置状态
				this.playStatus = true;
				this.playId = id;
				this.innerAudioContext = uni.createInnerAudioContext();
				this.innerAudioContext.src = url;

				this.innerAudioContext.play();
				this.msg('正在播放音频中...');

				// 监听播放错误事件
				this.innerAudioContext.onError((err) => {
					console.error('播放失败:', err);
				});
			} else {
				// 继续或暂停播放
				this.playStatus = !this.playStatus;
				if (this.playStatus) {
					this.innerAudioContext.play();
					this.msg('继续播放');
				} else {
					this.innerAudioContext.pause();
					this.msg('暂停播放');
				}
			}
			// 监听音频播放结束事件
			this.innerAudioContext.onEnded(() => {
				this.msg('音频播放结束');
				this.playStatus = false;
			});
		},
		downFile(data) {
			let power = this.powerInfo(data.c_time, data.status);
			if (power != 0) {
				return;
			}
			let self = this;
			let url = this.moxiConfig('domain') + 'plugin/tts/user/info/get_file';
			let param = this.requestParam({ id: data.id });
			// 下载文件
			// #ifdef H5 || WEB
			uni.request({
				url: url,
				method: 'GET',
				responseType: 'arraybuffer', // 关键：指定响应类型为二进制流
				data: {
					moxiPostData: JSON.stringify(param)
				},
				success: (res) => {
					if (res.statusCode === 200) {
						// 创建Blob对象
						const blob = new Blob([res.data], { type: 'audio/mpeg' });
						// 创建临时URL
						const downloadUrl = window.URL.createObjectURL(blob);

						// 创建虚拟a标签触发下载
						const link = document.createElement('a');
						link.href = downloadUrl;
						// 设置下载文件名（可从响应头获取或自定义）
						const fileName = data.name || 'audio.mp3';
						link.setAttribute('download', fileName);
						// 触发点击
						document.body.appendChild(link);
						link.click();
						// 清理资源
						document.body.removeChild(link);
						window.URL.revokeObjectURL(downloadUrl);

						self.msg('文件下载开始');
					}
				},
				fail: (err) => {
					console.error('下载失败:', err);
					self.msg('文件下载失败');
				}
			});
			// #endif

			// 小程序端下载后导出到本地download目录
			// #ifndef H5 || WEB
			uni.downloadFile({
				url: url + '?moxiPostData=' + JSON.stringify(param), // 文件的下载地址
				success: (downloadResult) => {
					if (downloadResult.statusCode === 200) {
						uni.saveFile({
							tempFilePath: downloadResult.tempFilePath, // 文件的临时路径
							success: (saveResult) => {
								// 获取本地已保存的文件列表。
								// 查找文件在列表中的索引
								uni.getSavedFileList({
									success: (fileList) => {
									}
								})
								self.msg('文件已保存至' + saveResult.savedFilePath);
							},
							fail: (err) => {
								self.msg('文件保存失败');
							}
						});
					}
				}
			});
			// #endif
		},
		scrolltolower() {
			if (this.status === 'loading') {
				this.getInfo.page++;
				this.get();
			}
		},
		get(page) {
			if (page) {
				this.getInfo.page = page;
			}
			// 获取列表数据
			this.moxiPost(
				'/plugin/tts/user/combineai/get_tts',
				this.getInfo,
				(res) => {
					if (this.status == 'nomore') return;
					if (this.data.length == 0) {
						this.data = res.data.data;
					} else {
						this.data = this.data.concat(res.data.data);
					}
					if (res.data.data.length < this.getInfo.page_num) {
						this.status = 'nomore';
					}
				}
			)
		}
	}
}
</script>

<style lang="scss" scoped>
.voice_manage {
	flex: 1;
	overflow: hidden;
	display: flex;

	.scrollY {
		flex: 1;
		overflow: hidden;

		.list {
			margin-top: 12px;
			display: flex;
			flex-direction: column;
			gap: 12px;
			padding: 0 8px;

			.item {
				background-color: #fff;
				border-radius: 8px;
				padding: 16px;

				display: flex;
				flex-direction: column;
				gap: 8px;

				.top {
					display: flex;
					justify-content: space-between;
					align-items: center;
					gap: 12px;

					.personInfo {
						flex: 1;
						display: flex;
						gap: 8px;
						align-items: center;

						.showImg {
							width: 32px;
							height: 32px;
							border-radius: 50%;
							overflow: hidden;

							.imageCss {
								width: 100%;
								height: 100%;
							}
						}

						.title {
							font-size: 14px;
							display: flex;
							gap: 8px;

							.commend {
								display: inline-flex;
								border-radius: 4px;
								color: #fff;
								padding: 0 8px;
								font-size: 10px;
								background-color: var(--bg-color);
							}
						}

						.name {
							font-size: 12px;
							color: #666;
						}
					}

					.controll {
						display: flex;
						align-items: center;
						gap: 8px;

						.circle {
							width: 24px;
							height: 24px;
							border-radius: 50%;
							background-color: var(--fail-color);
							display: flex;
							justify-content: center;
							align-items: center;

							&.red {
								background-color: #FF4949 !important;
							}
						}
					}
				}

				.tips {
					display: flex;
					justify-content: space-between;
					font-size: 10px;
					color: #999;

				}
			}
		}
	}
}
</style>
